package org.infosec.lc.exercises.esper.process;

import java.util.Iterator;

import org.infosec.lc.exercises.esper.listener.SimpleCepListener;
import org.infosec.lc.exercises.esper.listener.SimpleEspListener;
import org.infosec.lc.exercises.esper.modle.NormalizedEvent;

import com.espertech.esper.client.Configuration;
import com.espertech.esper.client.EPRuntime;
import com.espertech.esper.client.EPServiceProvider;
import com.espertech.esper.client.EPServiceProviderManager;
import com.espertech.esper.client.EPStatement;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.time.CurrentTimeEvent;
import com.espertech.esper.client.time.TimerControlEvent;

/**
	文件名：EsperProcessESP.java
	作  者：林超
	时  间：2011-6-22下午02:50:03

	功能描述：通过Esper-eql语言对ESP和CEP的处理
	
	EQL语法：
			 [insert into insert_into_def]
			 select select_list
			 from stream_def [as name][, stream_def [as name]][,...]
			 [where search_conditions]
			 [group by grouping_expression_list]
			 [having grouping_search_conditions]
			 [output output_specification]
			 [order by order_by_expression_list]
	聚合函数：
			sum,avg,count,max,min,median(中位数),stddev(标准偏差),avedev(计算平均差)
			
	HAVING 子句:
			在 SQL 中增加 HAVING 子句原因是，WHERE 关键字无法与合计函数一起使用。
				SELECT column_name, aggregate_function(column_name)
				FROM table_name
				WHERE column_name operator value
				GROUP BY column_name
				HAVING aggregate_function(column_name) operator value
	pom.xml	:
			
 */
public class EsperProcessESP {
	private EPServiceProvider esperEngine; // 实例化esper事件流处理引擎
	
	public EsperProcessESP() {
		Configuration config = new Configuration();
		
		/**
		 * 此处为编程引入Esper-config内的对象，也可通过XML（默认:esper.cfg.xml） 
		 * configuration.configure（“myengine.esper.cfg.xml”）;
		 * 
		 * 		<?xmlversion="1.0"encoding="UTF-8"?>
				<esper-configurationxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
										xsi:noNamespaceSchemaLocation="esper-configuration-1-0.xsd">
					<event-typealias="StockTick"class="net.esper.example.stockticker.event.StockTick"/>
					<event-typealias="PriceLimit"class="net.esper.example.stockticker.event.PriceLimit"/>
					<auto-importimport-name="org.mycompany.mypackage.MyUtility"/>
					<auto-importimport-name="org.mycompany.util.*"/>
				</esper-configuration>
		 */
//		config.addEventType("NormalizedEvent", NormalizedEvent.class);
		
		//添加包路径，这样在查询表达式中就不需要写类的全路径了 
		config.addEventTypeAutoName("org.infosec.lc.exercises.esper.modle");
		
		esperEngine = EPServiceProviderManager.getDefaultProvider(config);
	}

	/**
	 * 处理ESP-事件流
	 *  a是将myEvent事件集定义成长度为5的滑动窗口(.win:length(5))，也就是这个事件集里只保存最近的5个事件，
     	b是自定义一个窗口，这个窗口为无限制的(win:keepall())，可以往窗口里面插入任意的事件(可以指定).
	 */
	EPStatement statment = null;
	public void ProcessEsp(){
		String stmt;
		//查询最近30秒钟到达的NormalizedEvent事件平均价格  
		stmt = "Select Avg(threatrank) As avgRank, count(*) as countPerType From NormalizedEvent.win:time_batch(1.2 sec) having Avg(threatrank)>=7";
//		stmt = "insert into AlertEvent select *, count(*) as countPerType from NormalizedEvent.win:time_batch(2 sec)";
//		statment = esperEngine.getEPAdministrator().createEPL(stmt);
//		statment.addListener(new SimpleListener());
		
//		stmt = "select * from AlertEvent.win:length_batch(3) as alert where alert.threatrank > 6";
//		stmt = "select * from AlertEvent(threatrank > 6).win:length_batch(3)";
		
//		stmt = "select count(*) as countPerType from NormalizedEvent.win:length_batch(3)";
//		stmt = "select 'IDS' as type ,count(*) as countPerType from NormalizedEvent.win:length_batch(4) as s where threatrank > 6";
		statment = esperEngine.getEPAdministrator().createEPL(stmt);
		
		/**
		 * 此处得到Iterator为null，无意义
		 */
//		Iterator<EventBean> eventIter = statment.iterator();
//		System.out.println("------------");
//		for(;eventIter.hasNext();){
//			System.out.println("*******"+eventIter.next());
//		}
		
		statment.addListener(new SimpleEspListener());
		
	}
	
	/**
	 * 处理CEP-复杂事件处理
	 */
	public void ProcessCep(String pattern){
//		String pattern="a=AEvent->b=BEvent";
		EPStatement stmt=esperEngine.getEPAdministrator().createPattern(pattern);
		stmt.addListener(new SimpleCepListener());
	}
	
	/**
	 * 这将停止并删除在esperEngine的所有语句
	 */
	public void reset(){
		esperEngine.initialize();
	}
	
	/**
	 * 送esper引擎处理
	 * @param event
	 */
	public void sendEvent(Object event){
		esperEngine.getEPRuntime().sendEvent(event);// 送esper引擎处理
//		statment.addListener(new SimpleListener());
	}
}

